package com.rpc.bitcoin.bitcoin.controller;

import com.rpc.bitcoin.bitcoin.model.Result;
import com.spark.blockchain.rpcclient.Bitcoin;
import com.spark.blockchain.rpcclient.BitcoinException;
import com.spark.blockchain.rpcclient.BitcoinRPCClient;
import com.spark.blockchain.rpcclient.BitcoinUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.List;

/**
 * @Auther: MQS
 * @Date: 18/08/29 16:26
 * @Description:
 */
@RestController("/rpc")
public class RpcController {

    @Autowired
    private BitcoinRPCClient rpcClient;

    private Logger logger = LoggerFactory.getLogger(RpcController.class);

    /**
     *  区块高度
     * @return
     */
    @GetMapping("/height")
    public Result getHeight(){
        try {
            int height =rpcClient.getBlockCount();
            Result result = new Result(0,"success");
            result.setData(height - 1);
            return result;
        }
        catch (Exception e){
            e.printStackTrace();
            return Result.error(500,"查询失败,error:"+e.getMessage());
        }
    }

    /**
     *  生成地址
     * @param account
     * @return
     */
    @GetMapping("address/{account}")
    public Result getNewAddress(@PathVariable String account){
        logger.info("create new address :"+account);
        try {
            String address = rpcClient.getNewAddress(account);
            Result result = new Result(0,"success");
            result.setData(address);
            return result;
        }
        catch (BitcoinException e){
            e.printStackTrace();
            return Result.error(500,"rpc error:"+e.getMessage());
        }
    }

    /**
     *  查询余额
     * @param address
     * @return
     */
    @GetMapping("balance/{address}")
    public Result balance(@PathVariable String address){
        try {
            String account = rpcClient.getAccount(address);
            System.out.println("account="+account+",address="+address);
            BigDecimal balance = new BigDecimal(rpcClient.getBalance(account));
            Result result = new Result(0,"success");
            result.setData(balance);
            return result;
        }
        catch (Exception e){
            e.printStackTrace();
            return Result.error(500,"error:"+e.getMessage());
        }
    }

    /**
     *  钱包转账给指定地址
     * @param address
     * @param amount
     * @param fee
     * @return
     */
    @GetMapping({"transfer","withdraw"})
    public Result withdraw(String address, BigDecimal amount,BigDecimal fee){
        logger.info("withdraw:address={},amount={},fee={}",address,amount,fee);
        if(amount.compareTo(BigDecimal.ZERO) <= 0){
            return Result.error(500,"额度须大于0");
        }
        try {
            String txid = BitcoinUtil.sendTransaction(rpcClient,address,amount,fee);
            Result result = new Result(0,"success");
            result.setData(txid);
            return result;
        }
        catch (Exception e){
            e.printStackTrace();
            return Result.error(500,"error:"+e.getMessage());
        }
    }

    /**
     * 通过块hash 查询块
     * @param hash
     * @return
     */
    @GetMapping("/blockByHash/{hash}")
    public Result getBlock(@PathVariable String hash){
        try {
            Bitcoin.Block block = rpcClient.getBlock(hash);
            Result result = new Result(0,"success");
            result.setData(block);
            return result;
        }catch (BitcoinException e){
            e.printStackTrace();
            return Result.error(500,"error:"+e.getMessage());
        }
    }

    /**
     * 通过区块高度查询块
     * @param id
     * @return
     */
    @GetMapping("/blockById/{id}")
    public Result getBlock(@PathVariable Integer id){
        try {
            String hash = rpcClient.getBlockHash(id);
            Bitcoin.Block block = rpcClient.getBlock(hash);
            Result result = new Result(0,"success");
            result.setData(block);
            return result;
        }catch (BitcoinException e){
            e.printStackTrace();
            return Result.error(500,"error:"+e.getMessage());
        }
    }

    /**
     *  txId查询交易信息
     * @param txId
     * @return
     */
    @GetMapping("/getTrans/{txId}")
    public Result getTransaction(@PathVariable String txId){
        try {
            Bitcoin.RawTransaction rawTransaction = rpcClient.getTransaction(txId);
            Result result = new Result(0,"success");
            result.setData(rawTransaction);
            return result;
        }catch (BitcoinException e){
            e.printStackTrace();
            return Result.error(500,"error:"+e.getMessage());
        }
    }


//    public Result getTransactions(String account){
//        try {
//            List<Bitcoin.Transaction> transactions = rpcClient.listTransactions(account);
//            Result result = new Result(0,"success");
//            result.setData(transactions);
//            return result;
//        }catch (BitcoinException e){
//            e.printStackTrace();
//            return Result.error(500,"error:"+e.getMessage());
//        }
//    }


}
